package com.witmore.neutron.ai.web.controller;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jk.aliyun.oss.JkOssClient;
import com.jk.common.response.ResponseResult;
import com.witmore.neutron.ai.api.dto.ContentDTO;
import com.witmore.neutron.ai.api.dto.MessageContentDTO;
import com.witmore.neutron.ai.db.entity.AgentDO;
import com.witmore.neutron.ai.db.entity.AgentPublishConfigDO;
import com.witmore.neutron.ai.db.mapper.AgentMapper;
import com.witmore.neutron.ai.db.mapper.AgentPublishConfigMapper;
import com.witmore.neutron.ai.web.controller.bo.MessageBO;
import com.witmore.neutron.ai.web.controller.bo.MessageWebParam;
import com.witmore.neutron.ai.web.enums.PublishTypeEnum;
import com.witmore.neutron.ai.web.enums.ShowFlagEnum;
import com.witmore.neutron.ai.web.filter.AgentLoginRequired;
import com.witmore.neutron.ai.web.service.ChatClientRouterService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import static com.witmore.neutron.ai.web.constants.CommonConstant.OSS_FILE_UPLOAD_TP_PREFIX;
import static java.lang.String.format;

/**
 * Description: RobotController
 * Author: 豆子高
 * Date: 2025/5/15 15:03
 */
@Controller
@RequestMapping("/chat")
public class ChatController {

    @Autowired
    private JkOssClient jkOssClient;
    @Autowired
    private AgentMapper agentMapper;
    @Autowired
    private ChatClientRouterService chatClientRouterService;
    @Autowired
    private AgentPublishConfigMapper agentPublishConfigMapper;

    @AgentLoginRequired(value = "agentCode")
    @GetMapping("/{agentCode}")
    public String index(Model model,
                        @PathVariable("agentCode") String agentCode) {
        AgentDO agentDO = agentMapper.selectOne(new LambdaQueryWrapper<AgentDO>()
                .eq(AgentDO::getAgentCode, agentCode)
        );
        if (agentDO == null) {
            model.addAttribute("agentCode", agentCode);
            return "chatError";
        }
        // 服务发布状态
        AgentPublishConfigDO configDO = agentPublishConfigMapper.selectOne(new LambdaQueryWrapper<AgentPublishConfigDO>()
                .eq(AgentPublishConfigDO::getAgentId, agentDO.getId())
                .eq(AgentPublishConfigDO::getAgentCode, agentCode)
                .eq(AgentPublishConfigDO::getPublishType, PublishTypeEnum.WEB.getCode())
        );
        if (configDO == null) {
            model.addAttribute("agentCode", agentCode);
            return "chatError";
        }
        // 未发布
        if (configDO.getPublishStatus() == 0) {
            model.addAttribute("agentCode", agentCode);
            return "chatError";
        }
        model.addAttribute("timestamp", LocalDateTime.now());
        model.addAttribute("agent", agentDO);
        model.addAttribute("agentShowTitle", configDO.getAgentShowTitle());
        return "index";
    }


    @ResponseBody
    @PostMapping("/msg/{agentCode}")
    public ResponseResult<?> chat(@PathVariable("agentCode") String agentCode, @RequestBody MessageWebParam param) {
        MessageBO messageBO = new MessageBO();
        messageBO.setAgentCode(agentCode);
        messageBO.setAgentId(param.getAgentId());
        messageBO.setStream(param.getStream());
        messageBO.setSource(param.getSource());
        messageBO.setSessionId(param.getSessionId());
        messageBO.setMessages(this.getMessages(agentCode, null, param.getMessage()));
        ResponseResult<?> responseResult = chatClientRouterService.routeRequest(messageBO);
        if (responseResult == null || responseResult.getCode() != 200) {
            return ResponseResult.fail(1001, "服务器异常，请稍后再试");
        }
        return ResponseResult.success(responseResult.getData());
    }


    @ResponseBody
    @PostMapping("/upload/{agentCode}")
    public ResponseResult<?> handleUpload(@RequestParam("file") MultipartFile file,
                                          @RequestParam("agentId") Integer agentId,
                                          @RequestParam(value = "message", required = false) String message,
                                          @RequestParam(value = "stream") Boolean stream,
                                          @RequestParam(value = "source") String source,
                                          @RequestParam(value = "sessionId") String sessionId,
                                          @PathVariable("agentCode") String agentCode
    ) {

        if (file.isEmpty()) {
            return ResponseResult.fail(1001, "请上传有效的图片文件");
        }
        MessageBO messageBO = new MessageBO();
        messageBO.setAgentCode(agentCode);
        messageBO.setAgentId(agentId);
        messageBO.setStream(stream);
        messageBO.setSource(source);
        messageBO.setSessionId(sessionId);
        messageBO.setMessages(this.getMessages(agentCode, file, message));
        ResponseResult<?> responseResult = chatClientRouterService.routeRequest(messageBO);
        if (responseResult == null || responseResult.getCode() != 200) {
            return ResponseResult.fail(1001, "服务器异常，请稍后再试");
        }
        return ResponseResult.success(responseResult.getData());
    }


    private List<MessageContentDTO> getMessages(String agentCode, MultipartFile file, String message) {
        List<MessageContentDTO> messages = new ArrayList<>();
        // user角色的消息
        MessageContentDTO contentDTO = new MessageContentDTO();
        contentDTO.setRole("user");
        contentDTO.setShowFlag(ShowFlagEnum.SHOW.getCode());
        List<ContentDTO> contentList = new ArrayList<>();
        // user角色的消息 - 文本内容
        ContentDTO textContent = new ContentDTO();
        textContent.setType("text");
        textContent.setText(StringUtils.isEmpty(message) ? "（用户未提供输入）" : message);
        contentList.add(textContent);

        // user角色的消息 - 图片内容
        if (file != null && file.isEmpty()) {
            try {
                String fileName = format(OSS_FILE_UPLOAD_TP_PREFIX, agentCode) + System.currentTimeMillis() + ".jpg";
                String url = jkOssClient.uploadFile(fileName, file);
                ContentDTO imageContent = new ContentDTO();
                imageContent.setType("image_url");
                imageContent.setUrl(url);
                contentList.add(imageContent);

            } catch (Exception e) {
                throw new RuntimeException("图片上传失败: " + e.getMessage(), e);
            }
        }
        contentDTO.setContent(JSONArray.toJSONString(contentList));
        messages.add(contentDTO);
        return messages;
    }

}
